Overview
We have been tasked with cleaning and reorganizing four exisiting
data sets. The four data sets each contain different data related to
life expectancy in different countries. Our goal will be to combine them
into one that can be used for statistical analysis and
visualization.
3 of the 4 data sets are organized in a ‘wide’ format. For example,
the ‘income’ data set has 220 columns. Column 1 is the country of
interest, and each subsequent column is a year, from 1800-2018
(inclusive). Each year variable starts with a capital ‘X’.
Subsetting the Data to
Analyze the Year 2000
We have been asked to create a dataset for the year 2000 and
visualize it. First, we must create the data:
"2000data"<-subset(merge.df.2, year==2000)
#for some reason, R encounters an error while viewing "2000data", so I have created a second df that is identical
twothousanddata<-subset(merge.df.2, year==2000)
#write.csv(twothousanddata, "C:\\Users\\Alex\\Documents\\R\\Grad\\553\\datasets\\2000data.csv")
A copy of the above data can be found at https://raw.githubusercontent.com/AlexDragonetti/STA553/main/hw5/2000data.csv
Visualizing the Data
for the Year 2000
We have been asked to visually represent data from all four sets in
one graph, and specifically asked to represent region with a color-code.
Population size being represented with point size seems logical, meaning
our graph will have income on the X axis and Life Expectancy on the Y
axis. This uses the ggplot package.
life.exp.plot<-ggplot(twothousanddata, aes (x=income, y=lifeExp, color=region, size=population))+geom_point()+scale_color_manual(values=c("#332288", "#117733", "#88CCEE", "#CC6677", "#882255"))+
labs(
x="Income",
y="Life Expectancy",
size="Population",
color="Region",
title="Association Between Income and Life Expectancy")
life.exp.plot

Our graph shows evidence of a few trends: first, African and Asian
countries appear to have incredibly high variance for life expectancy.
Additionally, there appears to be a linear relationship between income
and life expectancy, but that (obviously) must stop somewhere. It
appears that beyond an average income of ~$40,000 (~$73,000 adjusted for
2024, using the US Bureau of Labor Statistics’ CPI Inflation
Calculator), the relationship between income and life expectancy
plateaus.
As this is only an analysis of one year, we would suggest analyzing
the relationship between income, population size, and life expectancy
across multiple years of interest to see if or how this relationship
changes, or what it averages to over an era of interest.
Using Interactive Plots
to Improve Visualization
While our previous plot provides an overview and can help assess
trends, we will use two interactive visuals to allow for deeper
engagement with data. Our first graph will look similar to our last, but
allow a reader to check a country (and its data). Our second will show
how the data has changed year to year. For our interactive plots, we
will use the plotly package.
First Interactive
plot: Income and Life Expectancy in 2015
df.full<-read.csv("https://raw.githubusercontent.com/AlexDragonetti/STA553/main/hw5/wk5.csv")
df.2015<-subset(df.full, year==2015)
plot_ly(
data=df.2015,
x=~income,
y=~lifeExp,
customdata=~population,
color=~factor(region),
hovertext=~country,
hoverlabel=~population,
size=~(log(population)),
alpha=.8,
type="scatter",
mode="markers",
hovertemplate=paste( '<br><b>Country</b>: %{hovertext}',
'<br><b>Income</b>: %{x}',
'<br><b>Life Expectancy</b>: %{y}',
'<br><b>Population</b>: %{customdata}'
)
) %>%
layout(
title=list(text= "Association of Income and Life Expectancy, 2015"
),
xaxis=list(title=list(text="Income"
)),
yaxis=list(title=list(text="Life Expectancy"
)))
The above graph is interactive with one’s mouse - if you move your
mouse over a dot, it will give you the following info for the specific
data point: country, income, life expectancy, and population. The region
(continent) continues to be color-coded.
Second Interactive
Plot: Visualizing the Data by Year
wong.pal <- c("#E69F00", "#56B4E9", "#009E73","#CC79A7", "#0072B2")
wong.pal <- setNames(wong.pal, c("Asia", "Europe", "Africa", "Americas", "Oceania"))
fig2 <- df.full %>%
plot_ly(
x = ~income,
y = ~lifeExp,
size = ~(2*log(population)-11)^2,
color = ~region,
colors = wong.pal,
frame = ~year,
text = ~paste("Country:", country,
"<br>Continent:", region,
"<br>Year:", year,
"<br>LifeExp:", lifeExp,
"<br>Pop:", population,
"<br>Income:", income),
hoverinfo = "text",
type = 'scatter',
mode = 'markers'
)%>%
layout(xaxis=list(title='Income'), yaxis=list(title='Life Expectancy'), title="Association of Income and Life Expectancy, 1800-2018")
fig2 <- fig2 %>% layout(
xaxis = list(
type = "log"
)
)
fig2
The above graph is able to represent all of the information from
previous visualizations over every available year. Please note the
scaling in the x axis, which allows a viewer to see a meaningful
difference in income, even at lower levels (without it, the first
century of data appears to show little horizontal change).
LS0tDQp0aXRsZTogIkNsZWFuaW5nIGFuZCBSZWZvcm1hdHRpbmcgRGF0YSBmb3IgSW50ZXJhY3RpdmUgVmlzdWFsaXphdGlvbiINCmF1dGhvcjogIkFsZXggRHJhZ29uZXR0aSINCmRhdGU6ICIzLTItMjAyNCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHRoZW1lOiBsdW1lbg0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KYGBgez1odG1sfQ0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQovKiBDYXNjYWRpbmcgU3R5bGUgU2hlZXRzIChDU1MpIGlzIGEgc3R5bGVzaGVldCBsYW5ndWFnZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwcmVzZW50YXRpb24gb2YgYSBkb2N1bWVudCB3cml0dGVuIGluIEhUTUwgb3IgWE1MLiBpdCBpcyBhIHNpbXBsZSBtZWNoYW5pc20gZm9yIGFkZGluZyBzdHlsZSAoZS5nLiwgZm9udHMsIGNvbG9ycywgc3BhY2luZykgdG8gV2ViIGRvY3VtZW50cy4gKi8NCg0KaDEudGl0bGUgeyAgLyogVGl0bGUgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIHRoZSByZXBvcnQgdGl0bGUgKi8NCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGF1dGhvcnMgICovDQogIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBkYXRlICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyAvKiBIZWFkZXIgMSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDEgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDIgc2VjdGlvbiB0aXRsZSAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCAzIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIGxldmVsIDQgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KPC9zdHlsZT4NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgRGV0ZWN0LCBpbnN0YWxsLCBhbmQgbG9hZCBwYWNrYWdlcyBpZiBuZWVkZWQuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZsZXQiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGVhZmxldCIpDQogICBsaWJyYXJ5KGxlYWZsZXQpDQp9DQppZiAoIXJlcXVpcmUoIkVudlN0YXRzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkVudlN0YXRzIikNCiAgIGxpYnJhcnkoRW52U3RhdHMpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiTUFTUyIpDQogICBsaWJyYXJ5KE1BU1MpDQp9DQppZiAoIXJlcXVpcmUoInBoeXRvb2xzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBoeXRvb2xzIikNCiAgIGxpYnJhcnkocGh5dG9vbHMpDQp9DQppZiAoIXJlcXVpcmUoImRwbHlyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImRwbHlyIikNCiAgIGxpYnJhcnkoZHBseXIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHlyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCiAgIGxpYnJhcnkodGlkeXIpDQp9DQppZiAoIXJlcXVpcmUoInN0cmluZ3IiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygic3RyaW5nciIpDQogICBsaWJyYXJ5KHN0cmluZ3IpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICAgbGlicmFyeShwbG90bHkpDQp9DQojIFNwZWNpZmljYXRpb25zIG9mIG91dHB1dHMgb2YgY29kZSBpbiBjb2RlIGNodW5rcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQoNCg0KDQojIE92ZXJ2aWV3DQoNCg0KV2UgaGF2ZSBiZWVuIHRhc2tlZCB3aXRoIGNsZWFuaW5nIGFuZCByZW9yZ2FuaXppbmcgZm91ciBleGlzaXRpbmcgZGF0YSBzZXRzLiBUaGUgZm91ciBkYXRhIHNldHMgZWFjaCBjb250YWluIGRpZmZlcmVudCBkYXRhIHJlbGF0ZWQgdG8gbGlmZSBleHBlY3RhbmN5IGluIGRpZmZlcmVudCBjb3VudHJpZXMuIE91ciBnb2FsIHdpbGwgYmUgdG8gY29tYmluZSB0aGVtIGludG8gb25lIHRoYXQgY2FuIGJlIHVzZWQgZm9yIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uLg0KDQozIG9mIHRoZSA0IGRhdGEgc2V0cyBhcmUgb3JnYW5pemVkIGluIGEgJ3dpZGUnIGZvcm1hdC4gRm9yIGV4YW1wbGUsIHRoZSAnaW5jb21lJyBkYXRhIHNldCBoYXMgMjIwIGNvbHVtbnMuIENvbHVtbiAxIGlzIHRoZSBjb3VudHJ5IG9mIGludGVyZXN0LCBhbmQgZWFjaCBzdWJzZXF1ZW50IGNvbHVtbiBpcyBhIHllYXIsIGZyb20gMTgwMC0yMDE4IChpbmNsdXNpdmUpLiBFYWNoIHllYXIgdmFyaWFibGUgc3RhcnRzIHdpdGggYSBjYXBpdGFsICdYJy4NCmBgYHtyLCBlY2hvPUZBTFNFfQ0KaXBwPC1yZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vZGF0YXNldHMvaW5jb21lX3Blcl9wZXJzb24uY3N2IikNCmxleTwtcmVhZC5jc3YoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL2RhdGFzZXRzL2xpZmVfZXhwZWN0YW5jeV95ZWFycy5jc3YiKQ0KcG9wPC1yZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vZGF0YXNldHMvcG9wdWxhdGlvbl90b3RhbC5jc3YiKQ0KY3I8LXJlYWQuY3N2KCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9kYXRhc2V0cy9jb3VudHJpZXNfdG90YWwuY3N2IikNCmBgYA0KDQoNCg0KIyBDbGVhbmluZyBhbmQgUmUtZm9ybWF0dGluZyB0aGUgRGF0YQ0KDQoNCldlIHdpbGwgZmlyc3QgY29uZGVuc2UgdGhvc2UgMyBkYXRhIHNldHMgdG8gYSBkYXRhIHNldCB3aXRoIDMgY29sdW1ucy4gVGhpcyB3aWxsIGFsbG93IGFuIGVhc2llciBtZXJnZS4gSW4gdGhlIHByb2Nlc3Mgb2YgZG9pbmcgdGhpcywgd2Ugd2lsbCByZW1vdmUgdGhlICJYIiBmcm9tIHRoZSBzdGFydCBvZiBlYWNoIHllYXIuDQpgYGB7cn0NCmlwcC5sb25nIDwtIGlwcCAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBzdGFydHNfd2l0aCgiWCIpLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImluY29tZSIpICU+JQ0KICBtdXRhdGUoeWVhciA9IGFzLm51bWVyaWMoc3RyX3JlbW92ZSh5ZWFyLCAiXlgiKSkpIA0KDQpsZXkubG9uZyA8LSBsZXkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gc3RhcnRzX3dpdGgoIlgiKSwgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJsaWZlRXhwIikgJT4lDQogIG11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhzdHJfcmVtb3ZlKHllYXIsICJeWCIpKSkgDQoNCnBvcC5sb25nIDwtIHBvcCAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBzdGFydHNfd2l0aCgiWCIpLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gInBvcHVsYXRpb24iKSAlPiUNCiAgbXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHN0cl9yZW1vdmUoeWVhciwgIl5YIikpKSANCmBgYA0KDQpXZSBoYXZlIGJlZW4gYXNrZWQgdG8gY3JlYXRlIGEgZGF0YXNldCBjYWxsZWQgYExpZmVFeHBJbmNvbWAgdGhhdCBvbmx5IGNvbnRhaW5zIExpZmUgRXhwZWN0YW5jeSBhbmQgSW5jb21lLiBUaGUgcmVxdWVzdGVkIGZvcm1hdCBpcyBsb3dlciBjYXNlIGZvciBhbGwgdmFyaWFibGVzIGV4Y2VwdCBmb3IgJ2xpZmVFeHAnIGZvciBsaWZlIGV4cGVjdGFuY3kuDQoNCldlIHdpbGwgYWxzbyBtZXJnZSB0aGUgcmVtYWluaW5nIGRhdGEgaW50byBvbmUgc2V0LiBUaGUgZmluYWwgZGF0YSBzZXRzIHdpbGwgcmVwbGFjZSAnZ2VvJyB3aXRoICdjb3VudHJ5JywgcGVyIHJlcXVlc3Qgb2Ygb3VyIGFzc2lnbm1lbnQuDQpgYGB7cn0NCkxpZmVFeHBJbmNvbSA8LSBtZXJnZShpcHAubG9uZywgbGV5LmxvbmcsIGJ5ID0gYygiZ2VvIiwgInllYXIiKSkNCg0KbWVyZ2UuZGYuMSA8LSBtZXJnZShMaWZlRXhwSW5jb20sIHBvcC5sb25nLCBieSA9IGMoImdlbyIsICJ5ZWFyIikpDQoNCmNvbG5hbWVzKGNyKVsxXTwtImdlbyINCm1lcmdlLmRmLjIgPC1tZXJnZShtZXJnZS5kZi4xLCBjciwgYnkgPSAiZ2VvIikNCg0KY29sbmFtZXMoTGlmZUV4cEluY29tKVsxXTwtImNvdW50cnkiDQpjb2xuYW1lcyhtZXJnZS5kZi4yKVsxXTwtImNvdW50cnkiDQoNCiN3cml0ZS5jc3YobWVyZ2UuZGYuMiwgIkM6XFxVc2Vyc1xcQWxleFxcRG9jdW1lbnRzXFxSXFxHcmFkXFw1NTNcXGRhdGFzZXRzXFx3azUuY3N2IikNCmBgYA0KDQpPdXIgZGF0YSBpcyBub3cgaW4gb25lIGRhdGFzZXQsIHJlYWR5IGZvciB2aXN1YWxpemF0aW9uLiBBIGNvcHkgb2YgdGhpcyBkYXRhIGNhbiBiZSBmb3VuZCBhdCBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQWxleERyYWdvbmV0dGkvU1RBNTUzL21haW4vaHc1L3drNS5jc3YNCg0KDQoNCiMgU3Vic2V0dGluZyB0aGUgRGF0YSB0byBBbmFseXplIHRoZSBZZWFyIDIwMDANCg0KDQpXZSBoYXZlIGJlZW4gYXNrZWQgdG8gY3JlYXRlIGEgZGF0YXNldCBmb3IgdGhlIHllYXIgMjAwMCBhbmQgdmlzdWFsaXplIGl0LiBGaXJzdCwgd2UgbXVzdCBjcmVhdGUgdGhlIGRhdGE6DQpgYGB7cn0NCiIyMDAwZGF0YSI8LXN1YnNldChtZXJnZS5kZi4yLCB5ZWFyPT0yMDAwKQ0KI2ZvciBzb21lIHJlYXNvbiwgUiBlbmNvdW50ZXJzIGFuIGVycm9yIHdoaWxlIHZpZXdpbmcgIjIwMDBkYXRhIiwgc28gSSBoYXZlIGNyZWF0ZWQgYSBzZWNvbmQgZGYgdGhhdCBpcyBpZGVudGljYWwNCnR3b3Rob3VzYW5kZGF0YTwtc3Vic2V0KG1lcmdlLmRmLjIsIHllYXI9PTIwMDApDQoNCiN3cml0ZS5jc3YodHdvdGhvdXNhbmRkYXRhLCAiQzpcXFVzZXJzXFxBbGV4XFxEb2N1bWVudHNcXFJcXEdyYWRcXDU1M1xcZGF0YXNldHNcXDIwMDBkYXRhLmNzdiIpDQpgYGANCg0KQSBjb3B5IG9mIHRoZSBhYm92ZSBkYXRhIGNhbiBiZSBmb3VuZCBhdCBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQWxleERyYWdvbmV0dGkvU1RBNTUzL21haW4vaHc1LzIwMDBkYXRhLmNzdiANCg0KDQojIFZpc3VhbGl6aW5nIHRoZSBEYXRhIGZvciB0aGUgWWVhciAyMDAwDQoNCldlIGhhdmUgYmVlbiBhc2tlZCB0byB2aXN1YWxseSByZXByZXNlbnQgZGF0YSBmcm9tIGFsbCBmb3VyIHNldHMgaW4gb25lIGdyYXBoLCBhbmQgc3BlY2lmaWNhbGx5IGFza2VkIHRvIHJlcHJlc2VudCByZWdpb24gd2l0aCBhIGNvbG9yLWNvZGUuIFBvcHVsYXRpb24gc2l6ZSBiZWluZyByZXByZXNlbnRlZCB3aXRoIHBvaW50IHNpemUgc2VlbXMgbG9naWNhbCwgbWVhbmluZyBvdXIgZ3JhcGggd2lsbCBoYXZlIGluY29tZSBvbiB0aGUgWCBheGlzIGFuZCBMaWZlIEV4cGVjdGFuY3kgb24gdGhlIFkgYXhpcy4gVGhpcyB1c2VzIHRoZSBgZ2dwbG90YCBwYWNrYWdlLg0KYGBge3J9DQpsaWZlLmV4cC5wbG90PC1nZ3Bsb3QodHdvdGhvdXNhbmRkYXRhLCBhZXMgKHg9aW5jb21lLCB5PWxpZmVFeHAsIGNvbG9yPXJlZ2lvbiwgc2l6ZT1wb3B1bGF0aW9uKSkrZ2VvbV9wb2ludCgpK3NjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzMzMjI4OCIsICIjMTE3NzMzIiwgIiM4OENDRUUiLCAiI0NDNjY3NyIsICIjODgyMjU1IikpKw0KICBsYWJzKA0KICB4PSJJbmNvbWUiLA0KICB5PSJMaWZlIEV4cGVjdGFuY3kiLA0KICBzaXplPSJQb3B1bGF0aW9uIiwNCiAgY29sb3I9IlJlZ2lvbiIsDQogIHRpdGxlPSJBc3NvY2lhdGlvbiBCZXR3ZWVuIEluY29tZSBhbmQgTGlmZSBFeHBlY3RhbmN5IikNCg0KbGlmZS5leHAucGxvdA0KYGBgDQoNCk91ciBncmFwaCBzaG93cyBldmlkZW5jZSBvZiBhIGZldyB0cmVuZHM6IGZpcnN0LCBBZnJpY2FuIGFuZCBBc2lhbiBjb3VudHJpZXMgYXBwZWFyIHRvIGhhdmUgaW5jcmVkaWJseSBoaWdoIHZhcmlhbmNlIGZvciBsaWZlIGV4cGVjdGFuY3kuIEFkZGl0aW9uYWxseSwgdGhlcmUgYXBwZWFycyB0byBiZSBhIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUgYW5kIGxpZmUgZXhwZWN0YW5jeSwgYnV0IHRoYXQgKG9idmlvdXNseSkgbXVzdCBzdG9wIHNvbWV3aGVyZS4gSXQgYXBwZWFycyB0aGF0IGJleW9uZCBhbiBhdmVyYWdlIGluY29tZSBvZiB+JDQwLDAwMCAofiQ3MywwMDAgYWRqdXN0ZWQgZm9yIDIwMjQsIHVzaW5nIHRoZSBVUyBCdXJlYXUgb2YgTGFib3IgU3RhdGlzdGljcycgQ1BJIEluZmxhdGlvbiBDYWxjdWxhdG9yKSwgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluY29tZSBhbmQgbGlmZSBleHBlY3RhbmN5IHBsYXRlYXVzLg0KDQpBcyB0aGlzIGlzIG9ubHkgYW4gYW5hbHlzaXMgb2Ygb25lIHllYXIsIHdlIHdvdWxkIHN1Z2dlc3QgYW5hbHl6aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUsIHBvcHVsYXRpb24gc2l6ZSwgYW5kIGxpZmUgZXhwZWN0YW5jeSBhY3Jvc3MgbXVsdGlwbGUgeWVhcnMgb2YgaW50ZXJlc3QgdG8gc2VlIGlmIG9yIGhvdyB0aGlzIHJlbGF0aW9uc2hpcCBjaGFuZ2VzLCBvciB3aGF0IGl0IGF2ZXJhZ2VzIHRvIG92ZXIgYW4gZXJhIG9mIGludGVyZXN0Lg0KDQoNCg0KIyBVc2luZyBJbnRlcmFjdGl2ZSBQbG90cyB0byBJbXByb3ZlIFZpc3VhbGl6YXRpb24NCg0KDQpXaGlsZSBvdXIgcHJldmlvdXMgcGxvdCBwcm92aWRlcyBhbiBvdmVydmlldyBhbmQgY2FuIGhlbHAgYXNzZXNzIHRyZW5kcywgd2Ugd2lsbCB1c2UgdHdvIGludGVyYWN0aXZlIHZpc3VhbHMgdG8gYWxsb3cgZm9yIGRlZXBlciBlbmdhZ2VtZW50IHdpdGggZGF0YS4gT3VyIGZpcnN0IGdyYXBoIHdpbGwgbG9vayBzaW1pbGFyIHRvIG91ciBsYXN0LCBidXQgYWxsb3cgYSByZWFkZXIgdG8gY2hlY2sgYSBjb3VudHJ5IChhbmQgaXRzIGRhdGEpLiBPdXIgc2Vjb25kIHdpbGwgc2hvdyBob3cgdGhlIGRhdGEgaGFzIGNoYW5nZWQgeWVhciB0byB5ZWFyLiBGb3Igb3VyIGludGVyYWN0aXZlIHBsb3RzLCB3ZSB3aWxsIHVzZSB0aGUgYHBsb3RseWAgcGFja2FnZS4NCg0KDQojIyBGaXJzdCBJbnRlcmFjdGl2ZSBwbG90OiBJbmNvbWUgYW5kIExpZmUgRXhwZWN0YW5jeSBpbiAyMDE1DQoNCg0KYGBge3J9DQpkZi5mdWxsPC1yZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0FsZXhEcmFnb25ldHRpL1NUQTU1My9tYWluL2h3NS93azUuY3N2IikNCg0KZGYuMjAxNTwtc3Vic2V0KGRmLmZ1bGwsIHllYXI9PTIwMTUpDQoNCnBsb3RfbHkoDQogIGRhdGE9ZGYuMjAxNSwNCiAgeD1+aW5jb21lLA0KICB5PX5saWZlRXhwLA0KICBjdXN0b21kYXRhPX5wb3B1bGF0aW9uLA0KICBjb2xvcj1+ZmFjdG9yKHJlZ2lvbiksDQogIGhvdmVydGV4dD1+Y291bnRyeSwNCiAgaG92ZXJsYWJlbD1+cG9wdWxhdGlvbiwNCiAgc2l6ZT1+KGxvZyhwb3B1bGF0aW9uKSksDQogIGFscGhhPS44LA0KICB0eXBlPSJzY2F0dGVyIiwNCiAgbW9kZT0ibWFya2VycyIsDQogIGhvdmVydGVtcGxhdGU9cGFzdGUoICAnPGJyPjxiPkNvdW50cnk8L2I+OiAle2hvdmVydGV4dH0nLA0KICAgICAgICAgICAgICAgICAgICAgICAgJzxicj48Yj5JbmNvbWU8L2I+OiAle3h9JywNCiAgJzxicj48Yj5MaWZlIEV4cGVjdGFuY3k8L2I+OiAle3l9JywNCiAgJzxicj48Yj5Qb3B1bGF0aW9uPC9iPjogJXtjdXN0b21kYXRhfScNCikNCikgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZT1saXN0KHRleHQ9ICJBc3NvY2lhdGlvbiBvZiBJbmNvbWUgYW5kIExpZmUgRXhwZWN0YW5jeSwgMjAxNSINCiAgICAgICAgICAgICApLA0KICAgIHhheGlzPWxpc3QodGl0bGU9bGlzdCh0ZXh0PSJJbmNvbWUiIA0KICAgICAgICAgICAgICApKSwNCiAgICB5YXhpcz1saXN0KHRpdGxlPWxpc3QodGV4dD0iTGlmZSBFeHBlY3RhbmN5IiANCiAgICAgICAgICAgICAgICkpKQ0KYGBgDQoNClRoZSBhYm92ZSBncmFwaCBpcyBpbnRlcmFjdGl2ZSB3aXRoICBvbmUncyBtb3VzZSAtIGlmIHlvdSBtb3ZlIHlvdXIgbW91c2Ugb3ZlciBhIGRvdCwgaXQgd2lsbCBnaXZlIHlvdSB0aGUgZm9sbG93aW5nIGluZm8gZm9yIHRoZSBzcGVjaWZpYyBkYXRhIHBvaW50OiBjb3VudHJ5LCBpbmNvbWUsIGxpZmUgZXhwZWN0YW5jeSwgYW5kIHBvcHVsYXRpb24uIFRoZSByZWdpb24gKGNvbnRpbmVudCkgY29udGludWVzIHRvIGJlIGNvbG9yLWNvZGVkLg0KDQoNCg0KIyMgU2Vjb25kIEludGVyYWN0aXZlIFBsb3Q6IFZpc3VhbGl6aW5nIHRoZSBEYXRhIGJ5IFllYXINCg0KDQpgYGB7cn0NCndvbmcucGFsIDwtIGMoIiNFNjlGMDAiLCAiIzU2QjRFOSIsICIjMDA5RTczIiwiI0NDNzlBNyIsICIjMDA3MkIyIikNCndvbmcucGFsIDwtIHNldE5hbWVzKHdvbmcucGFsLCBjKCJBc2lhIiwgIkV1cm9wZSIsICJBZnJpY2EiLCAiQW1lcmljYXMiLCAiT2NlYW5pYSIpKQ0KDQoNCmZpZzIgPC0gZGYuZnVsbCAlPiUNCiAgcGxvdF9seSgNCiAgICB4ID0gfmluY29tZSwgDQogICAgeSA9IH5saWZlRXhwLCANCiAgICBzaXplID0gfigyKmxvZyhwb3B1bGF0aW9uKS0xMSleMiwNCiAgICBjb2xvciA9IH5yZWdpb24sIA0KICAgIGNvbG9ycyA9IHdvbmcucGFsLCANCiAgICBmcmFtZSA9IH55ZWFyLCAgDQogICAgdGV4dCA9IH5wYXN0ZSgiQ291bnRyeToiLCBjb3VudHJ5LA0KICAgICAgICAgICAgICAgICAgIjxicj5Db250aW5lbnQ6IiwgcmVnaW9uLA0KICAgICAgICAgICAgICAgICAgIjxicj5ZZWFyOiIsIHllYXIsDQogICAgICAgICAgICAgICAgICAiPGJyPkxpZmVFeHA6IiwgbGlmZUV4cCwNCiAgICAgICAgICAgICAgICAgICI8YnI+UG9wOiIsIHBvcHVsYXRpb24sDQogICAgICAgICAgICAgICAgICAiPGJyPkluY29tZToiLCBpbmNvbWUpLA0KICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICB0eXBlID0gJ3NjYXR0ZXInLA0KICAgIG1vZGUgPSAnbWFya2VycycNCiAgKSU+JQ0KICBsYXlvdXQoeGF4aXM9bGlzdCh0aXRsZT0nSW5jb21lJyksIHlheGlzPWxpc3QodGl0bGU9J0xpZmUgRXhwZWN0YW5jeScpLCB0aXRsZT0iQXNzb2NpYXRpb24gb2YgSW5jb21lIGFuZCBMaWZlIEV4cGVjdGFuY3ksIDE4MDAtMjAxOCIpDQoNCmZpZzIgPC0gZmlnMiAlPiUgbGF5b3V0KA0KICB4YXhpcyA9IGxpc3QoDQogICAgdHlwZSA9ICJsb2ciDQogICkNCikNCg0KZmlnMg0KYGBgDQoNClRoZSBhYm92ZSBncmFwaCBpcyBhYmxlIHRvIHJlcHJlc2VudCBhbGwgb2YgdGhlIGluZm9ybWF0aW9uIGZyb20gcHJldmlvdXMgdmlzdWFsaXphdGlvbnMgb3ZlciBldmVyeSBhdmFpbGFibGUgeWVhci4gUGxlYXNlIG5vdGUgdGhlIHNjYWxpbmcgaW4gdGhlIHggYXhpcywgd2hpY2ggYWxsb3dzIGEgdmlld2VyIHRvIHNlZSBhIG1lYW5pbmdmdWwgZGlmZmVyZW5jZSBpbiBpbmNvbWUsIGV2ZW4gYXQgbG93ZXIgbGV2ZWxzICh3aXRob3V0IGl0LCB0aGUgZmlyc3QgY2VudHVyeSBvZiBkYXRhIGFwcGVhcnMgdG8gc2hvdyBsaXR0bGUgaG9yaXpvbnRhbCBjaGFuZ2UpLg==